#ifndef _NPC_HPP_
#define	_NPC_HPP_

/*******************************************************************************
 ** Name: NPC.hpp                                                             **
 ** Description:                                                              **
 **                                                                           **
 ** Open Source Initiative (OSI) Approved License                             **
 **                                                                           **
 **  Copyright (c) 2009-2010 Barry "Gian" James  <bjames@munixos.net>         **
 **  All rights reserved.                                                     **
 **                                                                           **
 **  Redistribution and use in source and binary forms, with or without       **
 **  modification, are permitted provided that the following conditions are   **
 **  met:                                                                     **
 **                                                                           **
 **  * Redistributions of source code must retain the above copyright notice, **
 **    this list of conditions and the following disclaimer.                  **
 **  * Redistributions in binary form must reproduce the above copyright      **
 **    notice, this list of conditions and the following disclaimer in the    **
 **    documentation and/or other materials provided with the distribution.   **
 **                                                                           **
 **  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS      **
 ** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED **
 ** TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A           **
 ** PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT        **
 ** HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,    **
 ** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED  **
 ** TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR    **
 ** PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF    **
 ** LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING      **
 ** NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS        **
 ** SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.              **
 **                                                                           **
 ******************************************************************************/
// Created on April 3, 2010, 6:57 PM
// Modified $Date: 2011-10-22 02:09:07 +0000 (Sat, 22 Oct 2011) $ by $Author: gian.james $

#define NPC_hpp_ID   "$Id: npc.hpp 146 2011-10-22 02:09:07Z gian.james $"

#include "object.hpp"
#include "stat.hpp"
//#include "program.hpp"

#define DEFAULT_NPC_AMMO_MAGS	3

// These are the commands/predicate that an NPC will respond to with a
// NPCNAME, COMMAND
class NPC;
struct NPCResponse
{
	std::string		predicate;
	void			(NPC::*func)(int,std::string,...);
};

// Type of available contacts
enum class ContactType {
	Professional, Government, Intelligence, Police,
	Military, Street, Crime
};

enum class NPCType { Human, Animal, Outlander, Swarm };

enum class NPCQualityType  {
	AllThumbs, AltID, AttackOnCmd, Augmented, Burrow, Camo, Captivating,
	CarryOnCmd, ClassAbility, Clumsy, Commander, Construct, DmgReduction,
	DmgResistance, DisarmOnCmd, Diurnal, EntertainOnCmd, ExtendedTraining,
	FastHealing, Fearless, Fearsome, Feat, Feral, Fleet, Flight, Foil,
	GuardOnCmd, Henchman, Horde, Horrific, Hulking, ImpHearing, ImpVision,
	ImpScent, InferiorAttr, LowLight, Mastermind, Meek, Minion, Mount,
	NaturalAttack, Nocturnal, NonCombatant, OpenDoorOnCmd, Prodigy,
	Rescue, RetrieveOnCmd, Seductive, SeekOnCmd, Skilled, Sluggish,
	Specialty, SquadItem, SquadWpn, Stalwart, PlotCritical, StrongMinded,
	StrongWilled, SubdueOnCmd, SuperiorAttr, Talented, Tough, Treacherous,
	Undersized, Unnerving,
	max
};
extern const char * NPCQualityTypeStr[];
extern const char * NPCGradeStr[];
extern const char * NPCDispositionStr[];
extern const char * NPCTraitStr[10][100];

struct NPCQuality
{
	NPCQualityType	type;
	stat::StatMod	mod;
	uint8_t			xpmod;
	NPCQuality *	next;
};

enum class NPCDisposition {
	Helpful, Supportive, Friendly, Intrigued, Neutral, Aloof,
	Unfriendly, Hostile, Adversarial,
	max
};

enum class NaturalAttackType {
	Bite, Claw, Tail, Trample, Unarmed,
	max
};

#define NPC_GRADE	0
#define NPC_THREAT	1
//! Scalable NPC statistics with ability to extend or collapse
//! to any given threat level and difficulty.  Inspiration and
//! data from Spycraft 2.0 (c) AEG, Inc and FantasyCraft 1.0.
struct NPCStatistics
{
	static int	initBonus[10][200];
	static int	attackBonus[10][200];
	static int 	defenseBonus[10][200];
	static int	resilienceBonus[10][200];
	static int	dmgSaveBonus[10][200];
	static int	vitalityPoints[10][200];
	static int	woundPoints[10][200];
	static int	competenceBonus[10][200];
	static int	skillBonus[10][200];
};

// NPC Flags
#define NPC_UNIQUE	0x0001

class Weapon;
class Ammo;
class NPC : public WorldObject
{
public:
    NPC(std::string n);
    NPC(const NPC &);
    virtual ~NPC();

    // consider lvl: all grades * threatLevel * numQualities
    void		do_consider(int,double);

    NPCType		Type() const { return type; }
    NPCQuality* Qualities() { return qualities; }
    std::list<WorldObject *> * Inventory() { return inventory; }
    std::string &	ProgramFile() { return progLocation; }
    uint8_t&	ThreatLvl()  { return threatLevel; }
    uint8_t&	InitGrade()  { return initGrade; }
    uint8_t&	AttackGrade()  { return attackGrade; }
    uint8_t&	DefenseGrade()  { return defenseGrade; }
    uint8_t&	ResilienceGrade()  { return resilienceGrade; }
    uint8_t&	DmgSaveGrade()  { return dmgSaveGrade; }
    uint8_t&	VitalityGrade()  { return vitalityGrade; }
    uint8_t&	WoundGrade()  { return woundGrade; }
    uint8_t&	CompetenceGrade()  { return competenceGrade; }
    uint8_t&	SkillGrade()  { return skillGrade; }
    int	&	XP() { return xp; }
    bool&		WillPursue()  { return bWillPursue; }

    NaturalAttackType NaturalAttack(NaturalAttackType nat = NaturalAttackType::max)
    { if (nat != NaturalAttackType::max) naturalAttackType = nat; return naturalAttackType; }
    flags16 &		Flags() { return flags; }

    virtual int	accept(Pattern::Visitor * v);

protected:
    uint16_t	threatLevel;
    uint8_t		initGrade;
    uint8_t		attackGrade;
    uint8_t		defenseGrade;
    uint8_t		resilienceGrade;
    uint8_t		dmgSaveGrade;
    uint8_t		vitalityGrade;
    uint8_t		woundGrade;
    uint8_t		competenceGrade;
    uint8_t		skillGrade;
    bool		bWillPursue;

    NPCType		type;
    NPCQuality *qualities;
    NaturalAttackType 	naturalAttackType;
    int			xp;

    std::list<WorldObject *> * inventory;

//    Program *	prog;	// npc's programming
    std::string	progLocation;

    flags16		flags;
};

class SignatureNPC : public NPC
{
public:
	SignatureNPC(const std::string & n);
	~SignatureNPC();

    void		SetBase(uint8_t stats[6]);
    Weapon *	Wpn(Weapon * w = NULL) { if (w) weapon = w; return weapon; }
    Ammo *		Ammunition(uint8_t n) { return ammo[n]; }
//    void		GiveAmmo(Ammo ** a) { &ammo[0] = a; }

protected:
	BaseStat 	base;
    Weapon *	weapon;
    Ammo *		ammo[DEFAULT_NPC_AMMO_MAGS];

};

// A special instance of an NPC
// We treat shopkeepers as a special case since they're so important
class Room;
class ShopKeeper : public NPC
{
public:

protected:
	Room *	shop;
};


#endif	/* _NPC_HPP_ */

